home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Tele / C / Comet2.1.3 Folder / Comet / asciitoken.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-21  |  15.5 KB  |  960 lines  |  [TEXT/????]

  1. /* token.c is the token handling routine, which is filled 
  2.  *  in with the routines executed when an action described by a token entry 
  3.  *  is found.
  4.  */
  5.  
  6. /*
  7.     Copyright Cornell University 1986.  All rights are reserved.
  8.  
  9. */
  10.  
  11. #include <em.h>
  12.  
  13. #include <cntldefs.h>
  14. #include <rcodes.h>
  15. #include <h19.h>
  16. #include <3270.h>
  17. #include <macdefs.h>
  18.  
  19. short asciiflush;            /* emdp->putflush needs to be called */
  20.  
  21. proc_token(tkptr)
  22. struct token *tkptr;
  23. {
  24.     switch(tkptr->class) {
  25.         case RSLT_ASCI: {
  26.             /* ascii character    */ 
  27.  
  28.             if (emdp->conntype == CONN_MACTCP
  29.                     || emdp->conntype == CONN_CUTCP) {
  30.                 if (tkptr->entry == TNIAC) 
  31.                     /* send IAC-IAC for IAC under Telnet */
  32.                     asciisendchar(TNIAC);
  33.             }    
  34.             if (tkptr->entry == X_OFF)
  35.                 emdp->userxoff = TRUE;
  36.             else
  37.                 emdp->userxoff = FALSE;
  38.                 
  39.             if (asciisendchar(tkptr->entry))
  40.                 /* no room to buffer character */
  41.                 return(-1);
  42.             break;
  43.         }
  44.         case RSLT_EDIT: {
  45.             if (stdedit(tkptr->entry)) {
  46.                 /* stdedit didn't handle the item */
  47.                 if (tkptr->entry == ED_PASTE) {
  48.                     /* TODO:  ASCII PASTE needs to be improved 
  49.                         take the current scrap & feed it into proc_token? 
  50.                         should handle echoing, timed line/character delays */
  51.                     long scraplen;
  52.                     unsigned char * thep;
  53.                     unsigned char thechar;
  54.                     long tickcount;
  55.                     
  56.                     scraplen = gettextscrap(&thep);
  57.                     while (scraplen-- > 0) {
  58.                         if ((thechar = *thep++) == CR) {
  59.                             /* do a CR/Line Feed when we see a CR */
  60.                             if (istcptype()) {
  61.                                 /* telnet, send CR-LF */
  62.                                 asciisendchar(CR);
  63.                                 asciisendchar(LF);
  64.                             }
  65.                             else {
  66.                                 if (emdp->ibm_keymode) {
  67.                                     asciisendchar(LF);    /* do LINE FEEDS like 3270 */
  68.                                 }
  69.                                 else {
  70.                                     asciisendchar(CR);
  71.                                     if (emdp->vtnewline)
  72.                                         asciisendchar(LF);
  73.                                 }
  74.                             }
  75.                             (*emdp->putflush)();
  76.                             Delay((long) 15, &tickcount);
  77.                                 /* wait to make sure tiny host buffers serviced */
  78.                                 /* TODO should handle by waiting for echo? */
  79.                             screen_service();
  80.                         }
  81.                         else {
  82.                             asciisendchar(thechar);
  83.                         }
  84.                     }
  85.                     releasescrap();
  86.                     break;
  87.                 }
  88.                 else
  89.                     entryerr(tkptr);
  90.             }
  91.             break;
  92.         }
  93.         case RSLT_PFKY: {
  94.             /* program function key, enter, clear for 7171 compatibility    */ 
  95.             int thepf;
  96.  
  97.             thepf = 0;
  98.             switch (tkptr->entry) {
  99.                 case PFSHIFT: {
  100.                     if (emdp->pfdubshift) 
  101.                         break;
  102.                     if (!emdp->pfshift) {
  103.                         emdp->pfshift = TRUE;
  104.                         pfshowshift();
  105.                     }
  106.                     else {
  107.                         emdp->pfshift = FALSE;
  108.                         pfclrshift();
  109.                     }
  110.                     break;
  111.                 }
  112.                 case PFDUBSHIFT: {
  113.                     if (emdp->pfshift) 
  114.                         break;
  115.                     if (emdp->pfdubshift) {
  116.                         emdp->pfdubshift = TRUE;
  117.                         pfshowdubshift();
  118.                     }
  119.                     else {
  120.                         emdp->pfdubshift = FALSE;
  121.                         pfclrdubshift();
  122.                     }
  123.                     break;
  124.                 }
  125.                 case PF1: 
  126.                 case PF2:
  127.                 case PF3: 
  128.                 case PF4:
  129.                 case PF5: 
  130.                 case PF6:
  131.                 case PF7:
  132.                 case PF8:
  133.                 case PF9:
  134.                 case PF10:
  135.                 case PF11:
  136.                 case PF12:
  137.                 case PF13:
  138.                 case PF14:
  139.                 case PF15:
  140.                 case PF16:
  141.                 case PF17:
  142.                 case PF18:
  143.                 case PF19:
  144.                 case PF20:
  145.                 case PF21:
  146.                 case PF22:
  147.                 case PF23:
  148.                 case PF24: {
  149.                     thepf = tkptr->entry;
  150.                     break;
  151.                 }
  152.                 case PA1: {
  153.                     sendpa1();
  154.                     break;
  155.                 }
  156.                 case PA2: {
  157.                     sendpa2();
  158.                     break;
  159.                 }
  160.                 case PA3: {
  161.                     sendpa3();
  162.                     break;
  163.                 }
  164.                 case CLEAR: {
  165.                     sendClear();
  166.                     break;
  167.                 }
  168.                 case ENTER: {
  169.                     sendEnter();
  170.                     break;
  171.                 }
  172.                 default: {
  173.                     entryerr(tkptr);
  174.                     break;
  175.                 }
  176.             }
  177.             if (thepf != 0) {
  178.                 /* a pf key should be sent */
  179.                 if (emdp->pfshift) {
  180.                     emdp->pfshift = FALSE;
  181.                     emdp->pfdubshift = FALSE;
  182.                     pfclrshift();
  183.                     pfclrdubshift();
  184.                     thepf += 12;
  185.                     tkptr->entry += 12; 
  186.                 }
  187.                 else if (emdp->pfdubshift) {
  188.                     emdp->pfshift = FALSE;
  189.                     emdp->pfdubshift = FALSE;
  190.                     pfclrshift();
  191.                     pfclrdubshift();
  192.                     thepf += 24;
  193.                     tkptr->entry += 24;
  194.                 }
  195.                 sendpf(thepf);
  196.             }
  197.             break;
  198.         }
  199.         case RSLT_MVCR: {
  200.             /* IBM cursor movement key 7171 compatibility */ 
  201.             switch (tkptr->entry) {
  202.                  case LEFT_ARROW:    {
  203.                     sendLeft(1);
  204.                      break;
  205.                 }
  206.                 case RIGHT_ARROW:  {
  207.                     sendRight(1);
  208.                     break;
  209.                 }    
  210.                 case UP_ARROW: {
  211.                     sendUp(1);
  212.                     break;
  213.                 }
  214.                 case DOWN_ARROW: {
  215.                     sendDown(1);
  216.                     break;
  217.                 }
  218.                 case HOME: {
  219.                     sendHome();
  220.                     break;
  221.                 }
  222.                 case NEW_LINE: {
  223.                     sendNewline();
  224.                     break;
  225.                 }
  226.                 case TAB_FWD: {
  227.                     sendTab();
  228.                     break;
  229.                 }
  230.                 case BACK_TAB: {
  231.                     sendBackTab();
  232.                     break;
  233.                 }
  234.                 default: {
  235.                     entryerr(tkptr);
  236.                 }
  237.             }
  238.             break;
  239.         }
  240.         case RSLT_LCAC: {
  241.             /* local action key    */ 
  242.             switch(tkptr->entry) {
  243.                 case BACKSP_BLANK: {
  244.                     sendBSblank();
  245.                     break;
  246.                 }
  247.                 case INSRT: {
  248.                     doinsert();
  249.                     break;
  250.                 }
  251.                 case ERASE_EOF: {
  252.                     sendErEOF();
  253.                     break;
  254.                 }
  255.                 case INPUT_ERASE: {
  256.                     sendErInput();
  257.                     break;
  258.                 }
  259.                 case BACKSP_DEL: {
  260.                     sendBSDEL();
  261.                     break;
  262.                 }
  263.                 case DEL_CHAR: {
  264.                     sendDEL();
  265.                     break;
  266.                 }
  267.                 case RESET: {
  268.                     sendReset();
  269.                     break;
  270.                 }
  271.                 default: {
  272.                     entryerr(tkptr);
  273.                 }
  274.             }
  275.             break;
  276.         }
  277.         case RSLT_YCURS: {
  278.             /* move to beginning of line y */
  279.             if (tkptr->entry < 0 || tkptr->entry > emdp->lastrow) {
  280.                 entryerr(tkptr);
  281.                 break;
  282.             }
  283.             emdp->gotoy = tkptr->entry;
  284.             break;
  285.         }
  286.         case RSLT_XCURS: {
  287.             /* move to an x location on current line */
  288.             if (tkptr->entry < 0 || tkptr->entry > lastcol) {
  289.                 entryerr(tkptr);
  290.                 break;
  291.             }
  292.             if (emdp->gotoy != -1) {
  293.                 cursmoveto(tkptr->entry, emdp->gotoy);
  294.                 emdp->gotoy = -1;
  295.             }
  296.             else {
  297.                 cursmoveto(tkptr->entry, ypos);
  298.             }
  299.             break;
  300.         }
  301.         default: {
  302.             if (stdtoken(tkptr))
  303.                 classerr(tkptr);
  304.         }
  305.     }
  306.     return(0);    
  307. }
  308.  
  309.  
  310. /* the following routines "send*" send  7171 translator specific sequences */
  311.  
  312. sendpf(pfkey)
  313. int pfkey;
  314. {
  315.     asciisendchar(ESC);
  316.  
  317.     switch (pfkey) {
  318.         case 1: {
  319.             asciisendchar('1');
  320.             break;
  321.         }
  322.         case 2: {
  323.             asciisendchar('2');
  324.             break;
  325.         }
  326.         case 3: {
  327.             asciisendchar('3');
  328.             break;
  329.         }
  330.         case 4: {
  331.             asciisendchar('4');
  332.             break;
  333.         }
  334.         case 5: {
  335.             asciisendchar('5');
  336.             break;
  337.         }
  338.         case 6: {
  339.             asciisendchar('6');
  340.             break;
  341.         }
  342.         case 7: {
  343.             asciisendchar('7');
  344.             break;
  345.         }
  346.         case 8: {
  347.             asciisendchar('8');
  348.             break;
  349.         }
  350.         case 9: {
  351.             asciisendchar('9');
  352.             break;
  353.         }
  354.         case 10: {
  355.             asciisendchar('0');
  356.             break;
  357.         }
  358.         case 11: {
  359.             asciisendchar('-');
  360.             break;
  361.         }
  362.         case 12: {
  363.             asciisendchar('=');
  364.             break;
  365.         }
  366.         case 13: {
  367.             asciisendchar('!');
  368.             break;
  369.         }
  370.         case 14: {
  371.             asciisendchar('@');
  372.             break;
  373.         }
  374.         case 15: {
  375.             asciisendchar('#');
  376.             break;
  377.         }
  378.         case 16: {
  379.             asciisendchar('$');
  380.             break;
  381.         }
  382.         case 17: {
  383.             asciisendchar('%');
  384.             break;
  385.         }
  386.         case 18: {
  387.             asciisendchar('^');
  388.             break;
  389.         }
  390.         case 19: {
  391.             asciisendchar('&');
  392.             break;
  393.         }
  394.         case 20: {
  395.             asciisendchar('*');
  396.             break;
  397.         }
  398.         case 21: {
  399.             asciisendchar('(');
  400.             break;
  401.         }
  402.         case 22: {
  403.             asciisendchar(')');
  404.             break;
  405.         }
  406.         case 23: {
  407.             asciisendchar('_');
  408.             break;
  409.         }
  410.         case 24: {
  411.             asciisendchar('+');
  412.             break;
  413.         }
  414.         default: {
  415.             error("Bad PF key code");
  416.         }
  417.     }
  418.     savescreen();
  419.         /* save the screen before it gets overwritten */
  420.  
  421. }
  422.  
  423. sendpa1()
  424. {
  425.     if (emdp->event_reg & TFTP_ON) {
  426.         /* cancel file transfer */
  427.         ft_usr();
  428.     }
  429.     else {
  430.         asciisendchar(ESC);
  431.         asciisendchar(',');
  432.  
  433.         savescreen();
  434.             /* save the screen before it gets overwritten */
  435.     
  436.     }
  437. }
  438.  
  439. sendpa2()
  440. {
  441.     asciisendchar(ESC);
  442.     asciisendchar('.');
  443.  
  444.     savescreen();
  445.         /* save the screen before it gets overwritten */
  446.  
  447. }
  448.  
  449. sendpa3()
  450. {
  451.     asciisendchar(ESC);
  452.     asciisendchar('/');
  453.  
  454.     savescreen();
  455.         /* save the screen before it gets overwritten */
  456.  
  457. }
  458.  
  459. sendClear()
  460. {
  461.     /* VT 7171 "keypad Enter" ? */
  462.     asciisendchar(ESC);
  463.     asciisendchar('?');
  464.     asciisendchar('M');
  465.  
  466.     savescreen();
  467.         /* save the screen before it gets overwritten */
  468.  
  469. }
  470.  
  471. sendInsert()
  472. {
  473.     /* VT 7171 "keypad ." */
  474.     asciisendchar(ESC);
  475.     asciisendchar('?');
  476.     asciisendchar('n');
  477. }
  478.  
  479. /* toggle the switches, control highlighting, and send insert */
  480.  
  481. doinsert()
  482. {
  483.     sendInsert();
  484.     if (emdp->event_reg & INSERT) {
  485.         clrinsert();
  486.         emdp->event_reg &= ~INSERT;
  487.     }
  488.     else {
  489.         showinsert();
  490.         emdp->event_reg |= INSERT;
  491.     }
  492. }
  493.  
  494.  
  495. sendEnter()
  496. {
  497.     asciisendchar(CR);
  498.  
  499.     savescreen();
  500.         /* save the screen before it gets overwritten */
  501.  
  502. }
  503.  
  504. sendNewline()
  505. {
  506.     asciisendchar(LF);
  507. }
  508.  
  509. sendBSDEL()
  510. {
  511.     sendLeft(1);
  512.     asciisendchar(DELETE);
  513. }
  514.  
  515. sendBSblank()
  516. {
  517.     sendLeft(1);
  518.     asciisendchar(' ');
  519.     sendLeft(1);
  520. }
  521.  
  522. sendTab()
  523. {
  524.     asciisendchar(TAB);
  525. }
  526.  
  527. sendBackTab()
  528. {
  529.     asciisendchar(ESC);
  530.     asciisendchar(TAB);
  531. }
  532.  
  533. sendDEL()
  534. {
  535.     asciisendchar(DELETE);
  536. }
  537.  
  538.  
  539. /* the vtaltcursor mode is only effective when in application keypad mode */
  540.  
  541. sendUp(count)
  542. int count;
  543. {
  544.     if (mode == VT100MODE) {
  545.         int appkeypadmode;
  546.         int altcursor;
  547.  
  548.         /* appkeypadmode = emdp->vtaltkeypad; incorrect, changed throughout ...  */
  549.         appkeypadmode = TRUE;
  550.         altcursor = emdp->vtaltcursor;
  551.         while (count--) {
  552.             asciisendchar(ESC);
  553.             asciisendchar(appkeypadmode ? altcursor : '[');
  554.             asciisendchar('A');
  555.         }
  556.     }
  557.     else {
  558.         while (count--) {
  559.             asciisendchar(ESC);
  560.             asciisendchar('A');
  561.         }
  562.     }
  563. }
  564.  
  565. sendDown(count)
  566. int count;
  567. {
  568.     if (mode == VT100MODE) {
  569.         int appkeypadmode;
  570.         int altcursor;
  571.  
  572.         appkeypadmode = TRUE;
  573.         altcursor = emdp->vtaltcursor;
  574.         while (count--) {
  575.             asciisendchar(ESC);
  576.             asciisendchar(appkeypadmode ? altcursor : '[');
  577.             asciisendchar('B');
  578.         }
  579.     }
  580.     else {
  581.         while (count--) {
  582.             asciisendchar(ESC);
  583.             asciisendchar('B');
  584.         }
  585.     }
  586. }
  587.  
  588. sendLeft(count)
  589. int count;
  590. {
  591.     if (mode == VT100MODE) {
  592.         int appkeypadmode;
  593.         int altcursor;
  594.  
  595.         appkeypadmode = TRUE;
  596.         altcursor = emdp->vtaltcursor;
  597.         while (count--) {
  598.             asciisendchar(ESC);
  599.             asciisendchar(appkeypadmode ? altcursor : '[');
  600.             asciisendchar('D');
  601.         }
  602.     }
  603.     else {
  604.         while (count--) {
  605.             asciisendchar(ESC);
  606.             asciisendchar('D');
  607.         }
  608.     }
  609. }
  610.  
  611. sendRight(count)
  612. int count;
  613. {
  614.     if (mode == VT100MODE) {
  615.         int appkeypadmode;
  616.         int altcursor;
  617.  
  618.         appkeypadmode = TRUE;
  619.         altcursor = emdp->vtaltcursor;
  620.         while (count--) {
  621.             asciisendchar(ESC);
  622.             asciisendchar(appkeypadmode ? altcursor : '[');
  623.             asciisendchar('C');
  624.         }
  625.     }
  626.     else {
  627.         while (count--) {
  628.             asciisendchar(ESC);
  629.             asciisendchar('C');
  630.         }
  631.     }
  632. }
  633.  
  634. sendHome()
  635. {
  636.     asciisendchar(BS);
  637. }
  638.  
  639. sendErInput()
  640. {
  641.     asciisendchar(ESC);
  642.     asciisendchar('?');
  643.     asciisendchar(DELETE);
  644. }
  645.  
  646. sendErEOF()
  647. {
  648.     asciisendchar(ESC);
  649.     asciisendchar(DELETE);
  650. }
  651.  
  652. sendReset()
  653. {
  654.     if (emdp->termtype != TERM_3270)
  655.         asciisendchar(CTLG);    /* ^G */
  656.  
  657.     savescreen();
  658.         /* save the screen before it gets overwritten */
  659.  
  660.     doreset();
  661. }
  662.  
  663.  
  664. /* move vi cursor to a vertical position yloc */
  665.  
  666. sendvvimove(yloc)
  667. int yloc;
  668. {
  669.     char temp[10];
  670.     register char * tempp = temp;
  671.  
  672.     sprintf(tempp, "%d", yloc + 1);
  673.     while (*tempp) {
  674.         asciisendchar(*tempp++);
  675.     }
  676.     asciisendchar('H');
  677.         /* vi command to move n lines from top of screen */
  678. }
  679.  
  680.  
  681. /* move vi cursor to a horizontal position xloc */
  682.  
  683. sendhvimove(xloc)
  684. int xloc;
  685. {
  686.     char temp[10];
  687.     register char * tempp = temp;
  688.  
  689.     sprintf(tempp, "%d", xloc + 1);
  690.     while (*tempp) {
  691.         asciisendchar(*tempp++);
  692.     }
  693.     asciisendchar('|');
  694.         /* vi command to move n lines from top of screen */
  695. }
  696.  
  697.  
  698. /* move emacs cursor to a vertical position yloc */
  699.  
  700. sendvemacsmove(yloc)
  701. int yloc;
  702. {
  703.     char temp[10];
  704.     register char * tempp = temp;
  705.  
  706.     sprintf(tempp, "%d", yloc);
  707.     while (*tempp) {
  708.         asciisendchar(*tempp++);
  709.     }
  710. /*    asciisendchar('H'); */
  711.         /* emacs command to move n lines from top of screen */
  712. }
  713.  
  714.  
  715. /* move emacs cursor to a horizontal position xloc */
  716.  
  717. sendhemacsmove(xloc)
  718. int xloc;
  719. {
  720.     char temp[10];
  721.     register char * tempp = temp;
  722.  
  723.     sprintf(tempp, "%d", xloc);
  724.     while (*tempp) {
  725.         asciisendchar(*tempp++);
  726.     }
  727. /*    asciisendchar('|'); */
  728.         /* emacs command to move n lines from top of screen */
  729. }
  730.  
  731.  
  732. /* Telnet sendchar: put out a character TODO local echo mode not healthy; should buffer line
  733.     to preserve WYSIWYG */
  734.  
  735. asciisendchar(schar)
  736. unsigned char schar;
  737. {
  738.     if (!emdp->connopen)
  739.         return(-1);
  740.  
  741.     if (emdp->event_reg & TFTP_ON)
  742.         /* if not abort char, don't send anything */
  743.         return(-1);
  744.         
  745.     if (emdp->ucb.u_sendm == EVERYC) {
  746.         if ((*emdp->putchar)(schar)) {
  747.             return(-1);
  748.         }
  749.         asciiflush = TRUE;
  750.     }
  751.     else {
  752.         if (emdp->vtnewline) {
  753.             /* LF will be the last char in the CR-LF output pair */
  754.             if (schar == LF) {
  755.                 asciiflush = TRUE;
  756.             }
  757.         }
  758.         else if (schar == CR) {
  759.             /* end of line, send */
  760.             asciiflush = TRUE;
  761.         }
  762.         if (asciiflush) {
  763.             if ((*emdp->putchar)(CR)) {
  764.                 return(-1);
  765.             }
  766.             if ((*emdp->putchar)(LF)) {
  767.                 /* in vtnewline mode, we'll have added the newline already */
  768.                 return(-1);
  769.             }
  770.         }
  771.         else {
  772.             if ((*emdp->putchar)(schar)) {
  773.                 return(-1);
  774.             }
  775.         }
  776.     }
  777.     if (emdp->ucb.u_echom == LOCAL) {
  778.         emprep();
  779.         if (schar == CR) {
  780.             (*emdp->em)(CR);
  781.             (*emdp->em)(LF);
  782.         }
  783.         else if (schar == LF) {
  784.             (*emdp->em)(LF);
  785.         }
  786.         else if ((schar >= ' ' && schar < DELETE) )
  787.             (*emdp->em)(schar);
  788.         else if (schar == C_BREAK || schar == CTLL) 
  789.             ;
  790.         else if (schar == BS || schar == DELETE) {
  791.             (*emdp->em)(BS);
  792.             (*emdp->em)(' ');
  793.             (*emdp->em)(BS);
  794.         }
  795.         else if (schar < ' ') {
  796.             /* make a control character */
  797.             (*emdp->em)('^');
  798.             (*emdp->em)((char) schar + '@');    
  799.         }
  800.         emend();
  801.     }
  802.     return(0);
  803. }
  804.  
  805. /* send a string of characters */
  806.  
  807. asciisendstr(strp)
  808. char * strp;
  809. {
  810.     if (emdp->event_reg & TFTP_ON)
  811.         /* if not abort char, don't send anything */
  812.         return(-1);
  813.         
  814.     for ( ; *strp; strp++) {
  815.         if ((*emdp->putchar)(*strp) ) {
  816.             return(-1);
  817.         }
  818.         if    (emdp->ucb.u_echom == LOCAL) {
  819.             emprep();
  820.             (*emdp->em)(*strp);
  821.             setcursor();
  822.             emend();
  823.         }
  824.     }
  825.     (*emdp->putflush)();
  826. }
  827.  
  828.  
  829. /* send a Break */
  830.  
  831. sendBreak()
  832. {
  833.     if (emdp->conntype == CONN_MACTCP
  834.         || emdp->conntype == CONN_CUTCP) {
  835.             sendcommand(TNINT);
  836.             sendsynch();
  837.     }
  838.     else if (emdp->conntype == CONN_SERD) {
  839.         sersendBreak();
  840.     }
  841. }
  842.  
  843.  
  844. /* send an IAC-command pair */
  845.  
  846. sendcommand(tncom)
  847. int tncom;
  848. {
  849.     (*emdp->putchar)(TNIAC);
  850.     (*emdp->putchar)((char) tncom);
  851.     (*emdp->putflush)();
  852. }
  853.  
  854. /* send a telnet Synch sequence--URG + DM, DM, to cause host to flush non-control data */
  855.  
  856. sendsynch()
  857. {
  858.     mtcpurgent();
  859.     sendcommand(TNDM);
  860.     mtcpclrurgent();
  861.     dotcpurgent();
  862. }
  863.  
  864.  
  865.  
  866. /* here follows a mess of download file transfer support */
  867. /* 2 short routines to get file transfer going */
  868.  
  869. /* for compatibility with c19 file transfer */
  870.  
  871. sendftchar(tchar)
  872. char tchar;
  873. {
  874.     (*emdp->putchar)(tchar);
  875. }
  876.  
  877.  
  878. /* move the cursor to the given x,y location */
  879.  
  880. cursmoveto(xloc, yloc)
  881. int xloc;
  882. int yloc;
  883. {
  884.     int count;
  885.  
  886.     if (emdp->ibm_keymode || (!emdp->curseekmode && ypos == yloc) ) {
  887.         /* if ibm_keymode, move up or down without going to the left margin */
  888.         /* else if on correct y move straight to emdp->xpos */
  889.         count = xpos - xloc;
  890.         if (count > 0) {
  891.             /* move left */
  892.             sendLeft(count);
  893.         }
  894.         else {
  895.             /* move right */
  896.             count = - count;
  897.             sendRight(count);
  898.         }
  899.         if (emdp->ibm_keymode) {
  900.             count = ypos - yloc;
  901.             if (count > 0) {
  902.                 /* move up */
  903.                 sendUp(count);
  904.             }
  905.             else {
  906.                 /* move down */
  907.                 count = -count;
  908.                 sendDown(count);
  909.             }
  910.         }
  911.     }
  912.     else if (emdp->curseekmode) {
  913.         /*  == CURVIMODE */
  914.         if (yloc != ypos)
  915.             sendvvimove(yloc);
  916.         if (xloc != xpos)
  917.             sendhvimove(xloc);
  918.     }
  919. #ifdef EMACSCAN
  920.     else if (emdp->curseekmode == CUREMACSMODE) {
  921.         if (yloc != ypos)
  922.             sendvemacsmove(yloc);
  923.         if (xloc != xpos)
  924.             sendhemacsmove(xloc);
  925.     }
  926. #endif
  927.     else {
  928.         /* slow standard method to move cursor to left margin */
  929.         if (yloc != ypos) {
  930.             sendLeft(xpos);
  931.     
  932.             /* move up or down */
  933.             count = ypos - yloc;
  934.             if (count > 0) {
  935.                 /* move up */
  936.                 sendUp(count);
  937.             }
  938.             else {
  939.                 /* move down */
  940.                 count = -count;
  941.                 sendDown(count);
  942.             }
  943.             sendRight(xloc);
  944.         }
  945.         /* move cursor left on same line */
  946.         else if (xloc < xpos) {
  947.             count = xpos - xloc;
  948.             sendLeft(count);
  949.         }
  950.         /* move cursor right on same line */
  951.         else if (xloc > xpos) {
  952.             count = xloc - xpos;
  953.             sendRight(count);
  954.         }
  955.     }
  956.     /* flush the output buffers now that we've sent out the moves */
  957.     (*emdp->putflush)();
  958. }
  959.  
  960.